﻿
Imports std
Imports usshare

Public Class asyncapi
    Public Event finishaction(ByVal info As info)

    Private _serverAddress As String = Nothing
    Private threads As threadpool = Nothing

    Public Class info
        Private _serverAddress As String
        Private _key As String
        Private _url As String
        Private _action As action

        Public shortUrl As String
        Public submitResult As submitResult
        Public keys As [set](Of String)
        Public actionResult As Boolean

        Public Function serverAddress() As String
            Return _serverAddress
        End Function

        Public Function key() As String
            Return _key
        End Function

        Public Function url() As String
            Return _url
        End Function

        Public Function action() As action
            Return _action
        End Function

        Public Sub New(ByVal serverAddress As String, ByVal key As String _
                       , ByVal url As String, ByVal action As action)
            copy(_serverAddress, serverAddress)
            copy(_key, key)
            copy(_url, url)
            copy(_action, action)
        End Sub
    End Class

    Private Sub workthread(ByVal obj As Object)
        Dim info As info = Nothing
        info = convertor.cast(Of info)(obj)
        assert(Not info Is Nothing, "info is nothing.")
        Select Case info.action()
            Case action.submit
                info.actionResult = api.submit(info.serverAddress(), info.key(), info.url() _
                                               , info.shortUrl, info.submitResult)
            Case action.preview
                info.actionResult = api.preview(info.serverAddress(), info.key(), info.shortUrl)
            Case action.urlkeys
                info.actionResult = api.urlkeys(info.serverAddress(), info.url(), info.keys)
            Case Else
                assert(False, "should cover all possibility.")
        End Select

        RaiseEvent finishaction(info)
    End Sub

    Public Sub submit(ByVal serverAddress As String, ByVal key As String, ByVal url As String)
        threads.insertJob(New info(serverAddress, key, url, action.submit))
    End Sub

    Public Sub submit(ByVal key As String, ByVal url As String)
        submit(serverAddress(), key, url)
    End Sub

    Public Sub preview(ByVal serverAddress As String, ByVal key As String)
        threads.insertJob(New info(serverAddress, key, Nothing, action.preview))
    End Sub

    Public Sub preview(ByVal key As String)
        preview(serverAddress(), key)
    End Sub

    Public Sub urlkeys(ByVal serverAddress As String, ByVal url As String)
        threads.insertJob(New info(serverAddress, Nothing, url, action.urlkeys))
    End Sub

    Public Sub urlkeys(ByVal url As String)
        urlkeys(serverAddress(), url)
    End Sub

    Public Function serverAddress() As String
        debugassert(Not isemptystring(_serverAddress), "have no valid serverAddress initialized.")
        Return _serverAddress
    End Function

    Public Sub initial(Optional ByVal serverAddress As String = Nothing, Optional ByVal threadCount As Int64 = 0)
        copy(_serverAddress, serverAddress)
        If threads Is Nothing Then
            threads = New threadpool(AddressOf workthread, threadCount)
        End If
    End Sub

    Public Sub New(Optional ByVal threadCount As Int64 = 0)
        initial(Nothing, threadCount)
    End Sub

    Public Sub New(ByVal serverAddress As String, Optional ByVal threadCount As Int64 = 0)
        initial(serverAddress, threadCount)
    End Sub

    Public Sub close()
        If Not threads Is Nothing Then
            threads.stop()
        End If
    End Sub
End Class
